package com.lsk.mps.backend.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.lsk.mps.backend.mapper.UserMapper;
import com.lsk.mps.backend.model.User;
import com.lsk.mps.backend.model.UserExcel;
import com.lsk.mps.backend.service.UserService;
import com.lsk.mps.backend.util.HashUtil;
import com.lsk.mps.backend.util.SecurityUtil;
import com.lsk.mps.backend.util.StatusCode;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper mapper;

    private static final int ITEMS_PER_PAGE = 10;

    public UserServiceImpl() {
        super();
    }

    @Override
    public void createUser(String username, String password, String role) {
        if (mapper.queryUserByName(username) != null) {
            throw new StatusCode(420, "User already exists");
        }
        User user = new User();
        user.setUsername(username);
        user.setPassword(HashUtil.sha256String(password));
        user.setRole(role);
        mapper.addUser(user);
    }

    @Override
    public void importUsersFromExcel(File file) {
        try {
            List<String> usernames = mapper.queryUsernames();
            EasyExcel.read(file, UserExcel.class, new ReadListener<UserExcel>() {
                @Override
                public void invoke(UserExcel data, AnalysisContext analysisContext) {
                    if (usernames.contains(data.getUsername())) {
                        throw new StatusCode(420, "User already exists");
                    }
                    User user = User.fromExcelUser(data);
                    mapper.addUser(user);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                }
            }).sheet().doRead();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void grantUser(Integer uid, String role) {
        mapper.updateRole(role, uid);
    }

    @Override
    public void deleteUser(Integer uid) {
        mapper.deleteUser(uid);
    }

    @Override
    public List<User> allUsers(Integer page) {
        int offset = (page - 1) * ITEMS_PER_PAGE;
        return mapper.queryAllUsers(offset, ITEMS_PER_PAGE);
    }

    @Override
    public Integer userTotalPages() {
        int count = mapper.userCount();
        return (int) Math.ceil(count / ((double) ITEMS_PER_PAGE));
    }

    @Override
    public void changeUsername(String newUsername) {
        if (mapper.queryUserByName(newUsername) != null) {
            throw new StatusCode(420, "User already exists");
        }
        Integer id = SecurityUtil.currentUID();
        mapper.updateUsername(newUsername, id);
    }

    @Override
    public void changePassword(String newPassword) {
        Integer id = SecurityUtil.currentUID();
        mapper.updatePassword(HashUtil.sha256String(newPassword), id);
    }
}
